package cn.kinoko.common.base.model;

import cn.kinoko.common.constant.HeaderConstant;
import cn.kinoko.common.utils.BeanHelper;
import cn.kinoko.common.utils.ThreadLocalUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;

/**
 * 服务层基类
 *
 * @author kinko
 */
public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> {
    @Override
    public boolean save(T entity) {
        LocalDateTime now = LocalDateTime.now();
        entity.setCreateTime(now);
        entity.setModifyTime(now);
        // 获取当前用户id
        Long uid = (Long) ThreadLocalUtil.get(HeaderConstant.UID_HEADER);
        setCreateAndModifyBy(entity, uid);
        return super.save(entity);
    }

    @Override
    public boolean saveBatch(Collection<T> entityList) {
        LocalDateTime now = LocalDateTime.now();
        // 获取当前用户id
        Long uid = (Long) ThreadLocalUtil.get(HeaderConstant.UID_HEADER);
        for (T entity : entityList) {
            entity.setCreateTime(now);
            entity.setModifyTime(now);
            setCreateAndModifyBy(entity, uid);
        }
        return super.saveBatch(entityList);
    }

    @Override
    public boolean saveOrUpdateBatch(Collection<T> entityList) {
        LocalDateTime now = LocalDateTime.now();
        // 获取当前用户id
        Long uid = (Long) ThreadLocalUtil.get(HeaderConstant.UID_HEADER);
        for (T entity : entityList) {
            if (entity.getCreateTime() == null) {
                entity.setCreateTime(now);
            }
            entity.setModifyTime(now);
            if (uid != null) {
                if (entity.getCreateBy() == null) {
                    entity.setCreateBy(uid);
                }
                entity.setModifyBy(uid);
            }
        }
        return super.saveOrUpdateBatch(entityList);
    }

    @Override
    public boolean updateById(T entity) {
        // 获取当前用户id
        Long uid = (Long) ThreadLocalUtil.get(HeaderConstant.UID_HEADER);
        if (uid != null) {
            entity.setModifyBy(uid);
        }
        entity.setModifyTime(LocalDateTime.now());
        return super.updateById(entity);
    }

    public boolean updateById(T entity, boolean timeChange) {
        // 获取当前用户id
        Long uid = (Long) ThreadLocalUtil.get(HeaderConstant.UID_HEADER);
        if (uid != null) {
            entity.setModifyBy(uid);
        }
        if (timeChange) {
            entity.setModifyTime(LocalDateTime.now());
        }
        return super.updateById(entity);
    }

    @Override
    public boolean updateBatchById(Collection<T> entityList) {
        // 获取当前用户id
        Long uid = (Long) ThreadLocalUtil.get(HeaderConstant.UID_HEADER);
        LocalDateTime now = LocalDateTime.now();
        for (T entity : entityList) {
            entity.setModifyTime(now);
            if (uid != null) {
                entity.setModifyBy(uid);
            }
        }
        return super.updateBatchById(entityList);
    }

    public boolean updateBatchById(Collection<T> entityList, boolean timeChange) {
        // 获取当前用户id
        Long uid = (Long) ThreadLocalUtil.get(HeaderConstant.UID_HEADER);
        Date now = new Date();
        for (T entity : entityList) {
            if (uid != null) {
                entity.setModifyBy(uid);
            }
            if (timeChange) {
                entity.setModifyTime(LocalDateTime.now());
            }
        }
        return super.updateBatchById(entityList);
    }

    /**
     * 设置创建人和修改人
     *
     * @param entity 实体
     * @param uid    用户id
     */
    private static <T extends BaseEntity> void setCreateAndModifyBy(T entity, Long uid) {
        if (uid != null) {
            if (entity.getCreateBy() == null) entity.setCreateBy(uid);
            if (entity.getModifyBy() == null) entity.setModifyBy(uid);
        }
    }

    /**
     * 转化成mybatis plus中的Page
     *
     * @param query 查询条件
     * @return IPage
     */
    public static <T> Page<T> getPage(BaseQuery query) {
        return new Page<>(query.getPage(), query.getSize());
    }

    /**
     * entityPage 转 VOPage
     *
     * @param page 基础分页
     * @return IPage
     */
    public static <T> Page<T> toVoPage(Page<?> page, Class<T> c) {
        return BeanHelper.copyPage(page, c);
    }
}
